home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 12 / Example 12.5 / skybox.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-06-30  |  7.3 KB  |  236 lines

  1. #include "skybox.h"
  2.  
  3. struct SKYBOX_VERTEX
  4. {
  5.     SKYBOX_VERTEX(D3DXVECTOR3 _pos, D3DXVECTOR2 _uv){ pos = _pos; uv = _uv; }
  6.     D3DXVECTOR3 pos;
  7.     D3DXVECTOR2 uv;
  8.     static const DWORD FVF;
  9. };
  10.  
  11. const DWORD SKYBOX_VERTEX::FVF = D3DFVF_XYZ | D3DFVF_TEX1;
  12.  
  13. SKYBOX::SKYBOX(IDirect3DDevice9 *Dev, char fileName[], float size)
  14. {
  15.     m_pDevice = Dev;
  16.     std::string endings[] = {"_UP.jpg", "_FR.jpg", "_BK.jpg", "_RT.jpg", "_LF.jpg", "_DN.jpg"};
  17.  
  18.     //Load the 6 Skybox m_textures
  19.     for(int i=0;i<6;i++)
  20.     {
  21.         std::string fName = fileName;
  22.         fName += endings[i];
  23.  
  24.         IDirect3DTexture9* newTexture = NULL;
  25.         D3DXCreateTextureFromFile(m_pDevice, fName.c_str(), &newTexture);
  26.         m_textures.push_back(newTexture);
  27.     }
  28.  
  29.     //Create Mesh
  30.     if(FAILED(D3DXCreateMeshFVF(12, 24, D3DXMESH_MANAGED, SKYBOX_VERTEX::FVF, m_pDevice, &m_pMesh)))
  31.         debug.Print("Failed to create SKYBOX m_pMesh");
  32.  
  33.     //Create vertices
  34.     SKYBOX_VERTEX* v = 0;
  35.     m_pMesh->LockVertexBuffer(0,(void**)&v);
  36.     
  37.     {
  38.         D3DXVECTOR3 corners[8] = {D3DXVECTOR3(-size,  size,  size),
  39.                                 D3DXVECTOR3( size,  size,  size),
  40.                                 D3DXVECTOR3(-size,  size, -size),
  41.                                 D3DXVECTOR3( size,  size, -size),
  42.                                 D3DXVECTOR3(-size, -size,  size),
  43.                                 D3DXVECTOR3( size, -size,  size),
  44.                                 D3DXVECTOR3(-size, -size, -size),
  45.                                 D3DXVECTOR3( size, -size, -size)};
  46.  
  47.         //Up Face
  48.         v[0]  = SKYBOX_VERTEX(corners[1], D3DXVECTOR2(0.0f, 0.0f));
  49.         v[1]  = SKYBOX_VERTEX(corners[0], D3DXVECTOR2(1.0f, 0.0f));
  50.         v[2]  = SKYBOX_VERTEX(corners[3], D3DXVECTOR2(0.0f, 1.0f));
  51.         v[3]  = SKYBOX_VERTEX(corners[2], D3DXVECTOR2(1.0f, 1.0f));
  52.         
  53.         //Front Face
  54.         v[4]  = SKYBOX_VERTEX(corners[0], D3DXVECTOR2(0.0f, 0.0f));
  55.         v[5]  = SKYBOX_VERTEX(corners[1], D3DXVECTOR2(1.0f, 0.0f));
  56.         v[6]  = SKYBOX_VERTEX(corners[4], D3DXVECTOR2(0.0f, 1.0f));
  57.         v[7]  = SKYBOX_VERTEX(corners[5], D3DXVECTOR2(1.0f, 1.0f));
  58.  
  59.         //Back Face
  60.         v[8]  = SKYBOX_VERTEX(corners[3], D3DXVECTOR2(0.0f, 0.0f));
  61.         v[9]  = SKYBOX_VERTEX(corners[2], D3DXVECTOR2(1.0f, 0.0f));
  62.         v[10] = SKYBOX_VERTEX(corners[7], D3DXVECTOR2(0.0f, 1.0f));
  63.         v[11] = SKYBOX_VERTEX(corners[6], D3DXVECTOR2(1.0f, 1.0f));
  64.  
  65.         //Right Face
  66.         v[12] = SKYBOX_VERTEX(corners[2], D3DXVECTOR2(0.0f, 0.0f));
  67.         v[13] = SKYBOX_VERTEX(corners[0], D3DXVECTOR2(1.0f, 0.0f));
  68.         v[14] = SKYBOX_VERTEX(corners[6], D3DXVECTOR2(0.0f, 1.0f));
  69.         v[15] = SKYBOX_VERTEX(corners[4], D3DXVECTOR2(1.0f, 1.0f));
  70.  
  71.         //Left Face
  72.         v[16] = SKYBOX_VERTEX(corners[1], D3DXVECTOR2(0.0f, 0.0f));
  73.         v[17] = SKYBOX_VERTEX(corners[3], D3DXVECTOR2(1.0f, 0.0f));
  74.         v[18] = SKYBOX_VERTEX(corners[5], D3DXVECTOR2(0.0f, 1.0f));
  75.         v[19] = SKYBOX_VERTEX(corners[7], D3DXVECTOR2(1.0f, 1.0f));
  76.  
  77.         //Down Face
  78.         v[20] = SKYBOX_VERTEX(corners[7], D3DXVECTOR2(0.0f, 0.0f));
  79.         v[21] = SKYBOX_VERTEX(corners[6], D3DXVECTOR2(1.0f, 0.0f));
  80.         v[22] = SKYBOX_VERTEX(corners[5], D3DXVECTOR2(0.0f, 1.0f));
  81.         v[23] = SKYBOX_VERTEX(corners[4], D3DXVECTOR2(1.0f, 1.0f));
  82.     }
  83.  
  84.     m_pMesh->UnlockVertexBuffer();
  85.  
  86.     //Calculate Indices
  87.     WORD* ind = 0;
  88.     m_pMesh->LockIndexBuffer(0,(void**)&ind);    
  89.  
  90.     int index = 0;
  91.     for(int quad=0;quad<6;quad++)
  92.     {
  93.         //First face
  94.         ind[index++] = quad * 4;
  95.         ind[index++] = quad * 4 + 1;
  96.         ind[index++] = quad * 4 + 2;
  97.  
  98.         //Second Face
  99.         ind[index++] = quad * 4 + 1;
  100.         ind[index++] = quad * 4 + 3;
  101.         ind[index++] = quad * 4 + 2;
  102.     }
  103.  
  104.     m_pMesh->UnlockIndexBuffer();
  105.  
  106.     //Set Attributes
  107.     DWORD *att = 0;
  108.     m_pMesh->LockAttributeBuffer(0,&att);
  109.  
  110.     //Set each quad to its own sub mesh
  111.     for(int i=0;i<12;i++)
  112.         att[i] = i / 2;
  113.  
  114.     m_pMesh->UnlockAttributeBuffer();
  115.  
  116.     //Set material
  117.     memset(&m_white, 0, sizeof(D3DMATERIAL9));
  118.     m_white.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
  119. }
  120.  
  121. SKYBOX::~SKYBOX()
  122. {
  123.     //Release m_textures
  124.     for(int i=0;i<m_textures.size();i++)
  125.         if(m_textures[i] != NULL)
  126.             m_textures[i]->Release();
  127.     m_textures.clear();
  128.  
  129.     //Release mesh
  130.     if(m_pMesh)m_pMesh->Release();
  131. }
  132.  
  133. void SKYBOX::Render(D3DXVECTOR3 cameraPos)
  134. {
  135.     //Set Renderstates
  136.     m_pDevice->SetRenderState(D3DRS_LIGHTING, false);
  137.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);
  138.     m_pDevice->SetRenderState(D3DRS_ZENABLE, false);
  139.  
  140.     m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  141.     m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
  142.  
  143.     //Set material
  144.     m_pDevice->SetMaterial(&m_white);
  145.  
  146.     //Move skybox to center on cameraPos
  147.     D3DXMATRIX position;
  148.     D3DXMatrixTranslation(&position, cameraPos.x, cameraPos.y, cameraPos.z);
  149.     m_pDevice->SetTransform(D3DTS_WORLD, &position);
  150.  
  151.     //Render the six sides of the skybox
  152.     for(int i=0;i<6;i++)
  153.     {
  154.         m_pDevice->SetTexture(0, m_textures[i]);
  155.         m_pMesh->DrawSubset(i);
  156.     }
  157.  
  158.     // Restore render states.
  159.     m_pDevice->SetRenderState(D3DRS_LIGHTING, true);
  160.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);
  161.     m_pDevice->SetRenderState(D3DRS_ZENABLE, true);
  162.     m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
  163.     m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
  164. }
  165.  
  166. void SKYBOX::GenerateEnvironmentMap(D3DXVECTOR3 position, bool saveToFile, TERRAIN &terrain)
  167. {
  168.     //Release m_textures
  169.     for(int i=0;i<m_textures.size();i++)
  170.         if(m_textures[i] != NULL)
  171.             m_textures[i]->Release();
  172.     m_textures.clear();
  173.  
  174.     std::string fNames[] = {"UP.jpg", "FR.jpg", "BK.jpg", "RT.jpg", "LF.jpg", "DN.jpg"};
  175.     
  176.     //The Projection matrix
  177.     D3DXMATRIX  proj;
  178.     D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, 1.0f, 1.0f, 1000.0f );
  179.     m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);
  180.  
  181.     D3DXVECTOR3 directions[] = {D3DXVECTOR3(0.0f, 1.0f, 0.0f),        //UP
  182.                                 D3DXVECTOR3(0.0f, 0.0f, -1.0f),        //Front
  183.                                 D3DXVECTOR3(0.0f, 0.0f, 1.0f),        //Back
  184.                                 D3DXVECTOR3(1.0f, 0.0f, 0.0f),        //Right
  185.                                 D3DXVECTOR3(-1.0f, 0.0f, 0.0f),        //Left
  186.                                 D3DXVECTOR3(0.0f, -1.0f, 0.0f)};    //Down
  187.  
  188.     //The camera "UP" direction for the 6 cameras
  189.     D3DXVECTOR3 up[] = {D3DXVECTOR3(0.0f, 0.0f, -1.0f),
  190.                         D3DXVECTOR3(0.0f, 1.0f, 0.0f),
  191.                         D3DXVECTOR3(0.0f, 1.0f, 0.0f),
  192.                         D3DXVECTOR3(0.0f, 1.0f, 0.0f),
  193.                         D3DXVECTOR3(0.0f, 1.0f, 0.0f),
  194.                         D3DXVECTOR3(0.0f, 0.0f, 1.0f)};
  195.  
  196.     LPDIRECT3DSURFACE9 backBuffer = NULL;
  197.     m_pDevice->GetRenderTarget(0,&backBuffer);
  198.  
  199.     for(int i=0;i<6;i++)
  200.     {
  201.         //Set the view matrix
  202.         D3DXMATRIX  view;
  203.         D3DXMatrixLookAtLH(&view, &position, &(position + directions[i]), &up[i]);
  204.         m_pDevice->SetTransform(D3DTS_VIEW, &view);
  205.  
  206.         //Create the render target texture & surface
  207.         LPDIRECT3DTEXTURE9 renderTexture = NULL;
  208.         LPDIRECT3DSURFACE9 renderSurface = NULL;
  209.         m_pDevice->CreateTexture(512, 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &renderTexture, NULL);
  210.         renderTexture->GetSurfaceLevel(0,&renderSurface);        
  211.  
  212.         //render to the texture
  213.         m_pDevice->SetRenderTarget(0, renderSurface);                            //set new render target
  214.         m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffffff, 1.0f, 0);    //clear texture
  215.         m_pDevice->BeginScene();
  216.  
  217.         CAMERA cam;
  218.         cam.Init(m_pDevice);
  219.         cam.CalculateFrustum(view, proj);
  220.         terrain.Render(cam, true);
  221.  
  222.         m_pDevice->EndScene();    
  223.  
  224.         //Save to file
  225.         if(saveToFile)D3DXSaveTextureToFile(fNames[i].c_str(), D3DXIFF_JPG, renderTexture, NULL);
  226.  
  227.         //Release variables
  228.         renderSurface->Release();
  229.         m_textures.push_back(renderTexture);
  230.     }
  231.  
  232.     //Restore rendertargets
  233.     m_pDevice->SetRenderTarget(0,backBuffer);
  234.     backBuffer->Release();
  235. }
  236.